package io.netty.test.main.chat;

import io.netty.channel.Channel;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.channel.group.ChannelGroup;
import io.netty.channel.group.DefaultChannelGroup;
import io.netty.util.concurrent.GlobalEventExecutor;

import java.time.LocalDate;

/**
 * Created by LuoYu on 2019/2/8.
 * 群聊服务端
 * - 通过channel池实现广播
 */
public class SockChatHandler extends SimpleChannelInboundHandler<String> {

    /**
     * channel池
     * 保存（注册）所有与服务端连接的channel对象
     * 可以对channel进行批量操作（广播）
     * channel之间的通信
     */
    private static ChannelGroup channels = new DefaultChannelGroup(GlobalEventExecutor.INSTANCE);
    //======================连接生命周期============================
    /**
     * 1.channel的tcp连接建立成功
     * 来自ChannelHandlerAdapter
     * 方法名表示该处理器作用于tcp连接时
     */
    @Override
    public void handlerAdded(ChannelHandlerContext ctx) throws Exception {
        Channel channel = ctx.channel();
        // 广播通知上线
        channels.writeAndFlush("【来自"+channel.remoteAddress()+"的网友】加入" + "\n");
        channels.add(channel);
    }

    /**
     *
     */
    @Override
    public void channelActive(ChannelHandlerContext ctx) throws Exception {
        Channel channel = ctx.channel();
        channels.writeAndFlush("【来自"+channel.remoteAddress()+"的网友】上线" + "\n");

    }

    /**
     *
     */
    @Override
    public void channelInactive(ChannelHandlerContext ctx) throws Exception {
        Channel channel = ctx.channel();
        channels.writeAndFlush("【来自"+channel.remoteAddress()+"的网友】下线" + "\n");

    }

    /**
     * channel的tcp连接断开
     */
    @Override
    public void handlerRemoved(ChannelHandlerContext ctx) throws Exception {
        Channel channel = ctx.channel();
        channels.writeAndFlush("【来自"+channel.remoteAddress()+"的网友】离开" + "\n");
//        channels.remove(channel); 断开连接后，会自动移除
    }

    /**
     * 消息处理逻辑
     * @param ctx           the {@link ChannelHandlerContext} which this {@link SimpleChannelInboundHandler}
     *                      belongs to
     * @param msg           the message to handle
     */
    @Override
    protected void channelRead0(ChannelHandlerContext ctx, String msg) throws Exception {
        Channel channel = ctx.channel();
        channels.forEach(ch -> {
            if (channel != ch) {
                ch.writeAndFlush("【来自"+channel.remoteAddress()+"的网友】说:"+msg + "\n");
            } else {
                ch.writeAndFlush("【我】说:"+msg + "\n");   
            }
        });
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        super.exceptionCaught(ctx, cause);
        ctx.close();
    }
}
